package com.aljfce.business.profile.control;

import com.aljfce.business.profile.exception.UserNotFoundException;
import com.aljfce.business.entity.Calendar;
import com.aljfce.business.entity.CalendarPK;
import com.aljfce.business.entity.User;
import com.aljfce.business.mail.control.MailManager;
import com.aljfce.business.mail.exception.InvalidMessageException;
import com.aljfce.business.mail.exception.InvalidRecipientException;
import com.aljfce.business.mail.exception.InvalidSubjectException;
import com.aljfce.business.profile.utils.Groups;
import java.security.Principal;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.mail.MessagingException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author Antonio
 */
@Named
@Stateless
public class ProfileManager {
    
    @PersistenceContext
    private EntityManager em;
    
    @Inject
    private MailManager registrationMail;
    /**
     * Default constructor
     */
    public ProfileManager() {
    }
    
    /**
     * This method looks for a {@link User} in the database and returns it to the caller
     *
     * @param email A {@link String} representing the searched user's email which is the user's primary key.
     * @return  The sarched {@link User} object.
     */
    public User getProfile (String email) throws UserNotFoundException{
        
        if (email == null) {
            throw new IllegalArgumentException("Email cannot be null");
        }
        
        User user = em.find(User.class, email);
        
        if (user == null) {
            throw new UserNotFoundException("User is not present in the persistence context");
        }
        
        return user;
    }
    
    //this is present in the design document but useless
    public void checkProfile(){
    }
    
    /**
     * This method will associates to the {@link User} a default {@link Calendar} object 
     * and persist them in the persistence context.
     * The method also sends an email to the User's email address to notifies the registration.
     * 
     * @param user The {@link User} to save in the persistence context.
     * @param password A {@link String} representing the user's password.
     */
    public Boolean newProfile(User user, String password) {
        
        if (user == null||password == null) {
            throw new IllegalArgumentException("User e/o password cannot be null");
        }
        
        if (em.find(User.class, user.getEmail())!=null)
            return true;
        
        user.setPassword(password);
        user.setGroupName(Groups.USER);
        em.persist(user);
       
        CalendarPK cPK = new CalendarPK(user.getEmail());
        
        Calendar calendar = new Calendar (cPK);
        calendar.setUser(user);
        em.persist(calendar);
        
        try {
            registrationMail.sendRegistrationMsg(user, password);
        } catch (IllegalArgumentException | MessagingException | InvalidSubjectException | InvalidRecipientException | InvalidMessageException ex) {
            Logger.getLogger(ProfileManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }
    
    /**
     * This method will save the modified information abaout a {@link User} in the persistence context
     *
     * @param name The {@link User}'s new name.
     * @param surname The {@link User}'s new surname.
     * @param password The {@link User}'s new password.
     * @return  The {@link User} saved in the persistence context.
     */
    public User saveProfile (String name, String surname, String password){
        
        if (name == null||surname == null) {
            throw new IllegalArgumentException("Name e/o surname cannot be null");
        }
        
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        
        Principal principal = request.getUserPrincipal();
        
        User current = em.find(User.class, principal.getName());
        
        current.setName(name);
        current.setSurname(surname);
        if(password != null && !password.isEmpty())
            current.setPassword(password);
        
        return em.merge(current);
    }
    
    /**
     * This method seeks a {@link User} object and removes it from the persistence context.
     *
     * @param email A {@link String} representing the searched user's email which is the user's primary key.
     */
    public void deleteProfile(String email) throws UserNotFoundException {
        
        if (email == null) {
            throw new IllegalArgumentException("Email cannot be null");
        }          
        
        User current = em.find(User.class, email);
        if (current == null) {
            throw new UserNotFoundException("User is not present in the persistence context");
        }
        
        em.remove(current);
   }
}
